﻿using Heroius.Extension;
using System;
using System.Linq;
using System.Xml.Linq;

namespace EnvSafe.Open.EPE.Vent.GB15605_2017
{

    /// <summary>
    /// EN经验公式
    /// </summary>
    public class BuildingEntity : GB15605_2008.BuildingEntity
    {
        public BuildingEntity()
        {
            // set values to avoid 2008 predication
            p = 999;
        }

        /// <summary>
        /// 建筑物内表面积，㎡
        /// </summary>
        public double ASurface { get; set; }

        PredicateResult Predicate()
        {
            if (predmax > 0.01)
            {
                return new PredicateResult(PredicateResult.Code_Over, "最大受控爆炸压力 不应超出0.01MPa");
            }
            if ((predmax-pstat)<0.002)
            {
                return new PredicateResult(PredicateResult.Code_NotBigEnough, "最大受控爆炸压力 应比 静开启压力 至少高 0.002MPa");
            }
            if (kst > 30)
            {
                return new PredicateResult(PredicateResult.Code_Over, "Kst超出适用范围(30MPa.m/s)");
            }
            //todo: 细长房屋，以及细长房屋中非圆形或方形截面的，需要进一步验证
            return PredicateResult.Succeed;
        }

        public override CalcResult Calculate()
        {
            CalcResult r = new CalcResult(1);
            var p_f = Predicate();
            if (p_f.IsSucceed)
            {
                Utility.DoTransform(p_f.Transforms);
                try
                {
                    double C;
                    if (kst > 20)
                    {
                        C = 0.0095;
                    }
                    else if (kst > 10)
                    {
                        C = 0.0082;
                    }
                    else
                    {
                        C = 0.0057;
                    }
                    r.Results[0] = C * ASurface * Math.Pow(predmax, -0.5);
                    r.Succeed = true;
                }
                catch
                {
                    r.Succeed = false;
                    r.Remarks.Add("计算出错");
                }
                Utility.UndoTransform(p_f.Transforms);

                if (r.Succeed)
                {
                    r.MergeRemarks(p_f.Transforms.Select(item => $"已转换: {item.Description}"));
                }
            }
            else
            {
                r.Succeed = false;
                r.Remarks.Add($"计算不适用：{p_f.Description}");
            }
            return r;
        }

        public override void RaiseAllPropertiesChangedEvent()
        {
            base.RaiseAllPropertiesChangedEvent();
            RaisePropertyChangedEvent("ASurface");
        }

        public override string GenXml()
        {
            return $"{base.GenXml()}<ext><ASurface>{ASurface}</ASurface></ext>";
        }

        public override void ReadXml(XElement element)
        {
            base.ReadXml(element);
            ASurface = element.Element("ext").Element("ASurface").Value.As<double>();
        }
    }

    /// <summary>
    /// GB15605-2017/EN14491-2012 的管道防爆：根据设计压力确定泄爆片的间隔距离
    /// </summary>
    public class PipeEntity : GB15605_2008.PipeEntity
    {
        public PipeEntity()
        {
            // set values to avoid 2008 predication

        }

        PredicateResult Predicate()
        {
            if (predmax > 0.05)
            {
                return new PredicateResult(PredicateResult.Code_Over, "最大泄爆压力 不应超出0.05MPa");
            }
            if (kst > 30)
            {
                return new PredicateResult(PredicateResult.Code_Over, "Kst超出适用范围(30MPa.m/s)");
            }
            return PredicateResult.Succeed;
        }

        public override CalcResult Calculate()
        {
            CalcResult r = new CalcResult(1);
            var p_f = Predicate();
            if (p_f.IsSucceed)
            {
                double ldd;
                Utility.DoTransform(p_f.Transforms);
                if (kst > 20)
                {
                    ldd = 63.76 - 62.42 * Math.Pow(Math.E, -1.484 * p);
                    r.Succeed = (ldd <= 50);
                }
                else if (kst > 10)
                {
                    ldd = 88.57 - 81.99 * Math.Pow(Math.E, -1.64 * p);
                    r.Succeed = (ldd <= 50);
                }
                else
                {
                    ldd = 324.8 * (1 - Math.Pow(Math.E, -1.072 * p));
                    r.Succeed = (ldd <= 100);
                }
                Utility.UndoTransform(p_f.Transforms);

                if (r.Succeed)
                {
                    r.Results[0] = ldd * d;
                    r.MergeRemarks(p_f.Transforms.Select(item => $"已转换: {item.Description}"));
                }
                else
                {
                        r.Remarks.Add("长径比超出校验范围，计算失败");
                }
            }
            else
            {
                r.Succeed = false;
                r.Remarks.Add($"计算不适用：{p_f.Description}");
            }
            return r;
        }
    }
}
